package org.niux.aims.common.filter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class UserLoginFilter implements Filter{
	
	private Log log = LogFactory.getLog(this.getClass());
	
	protected static final String INIT_PARAM_NAME = "publicURIs";
	
	private static ServletContext SERVLET_CONTEXT;
	
	public void destroy() {
		UserLoginFilter.SERVLET_CONTEXT = null;
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		log.debug("用户登录检测");
		
		HttpServletRequest httpServletRequest = (HttpServletRequest) request;
		HttpServletResponse httpServletResponse = (HttpServletResponse) response;
		String requesturi = httpServletRequest.getRequestURI();
		
		// 通过检查session中的变量，过虑请求
		HttpSession session = httpServletRequest.getSession();
		// 当前会话用户为空而且不是请求登录，退出登录，欢迎页面和根目录则退回到应用的根目录

		log.debug("请求URL："+requesturi);
		
		/** 如果请求的URI是公共URI，忽略访问控制 */
		if(this.isPublicURIs(httpServletRequest)) {
			chain.doFilter(request, response);
			return;
		}
		
		if(this.isForbidden(httpServletRequest)) {
			log.debug("用户登录信息失效");
			session.setAttribute("session_timeout", "timeout");
			httpServletRequest.getSession().setAttribute("ctx", httpServletRequest.getContextPath());
			httpServletRequest.getSession().setAttribute("msg", "timeout");
			httpServletResponse.sendRedirect(httpServletRequest.getContextPath());
			return;
		}
		
		//加入filter链继续向下执行
		chain.doFilter(request, response);
	}

	/**
	 * 
	 * 方法概述：初始化过滤器
	 * 描述：初始化过滤器
	 * @param filterConfig
	 * @throws ServletException
	 * 返回类型：
	 * 修改人：梁铭显
	 * 修改时间：2013-7-29
	 */
	public void init(FilterConfig filterConfig) throws ServletException {
		log.info("初始化过滤器");
		UserLoginFilter.SERVLET_CONTEXT = filterConfig.getServletContext();
	}

	/**
	 * 
	 * 方法概述：检查是否公共页面
	 * 描述：检查是否公共页面
	 * @param httpServletRequest
	 * @return
	 * 返回类型：boolean
	 * 修改人：梁铭显
	 * 修改时间：2013-7-29
	 */
	protected boolean isPublicURIs(HttpServletRequest httpServletRequest) {
		String requestURI = httpServletRequest.getRequestURI();
		for(String publicURI : this.getPublicURIs()) {
			if(requestURI.indexOf(publicURI)!=-1)
				return true;
		}
		return false;
	}
	
	/**
	 * 
	 * 方法概述：获取公共页面
	 * 描述：获取公共页面
	 * @return
	 * 返回类型：List<String>
	 * 修改人：梁铭显
	 * 修改时间：2013-7-29
	 */
	protected List<String> getPublicURIs() {
		List<String> publicURIs = new ArrayList<String>();
		String publicURIsStr = UserLoginFilter.SERVLET_CONTEXT.getInitParameter(INIT_PARAM_NAME);
		if (publicURIsStr != null) {
			publicURIs = Arrays.asList(publicURIsStr.split(" "));

		}
		return publicURIs;
	}
	
	/**
	 * 
	 * 方法概述：判断是否有登录权限
	 * 描述：判断是否有登录权限
	 * @param httpServletRequest
	 * @return
	 * 返回类型：boolean
	 * 修改人：梁铭显
	 * 修改时间：2013-7-29
	 */
	private boolean isForbidden(HttpServletRequest httpServletRequest) {
		HttpSession session = httpServletRequest.getSession();
		Object currentUser = session.getAttribute("account");
		return (currentUser == null && !this.isPublicURIs(httpServletRequest));
	}
}
